#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
#include <linux/cred.h>
#include <linux/list.h>
#include <linux/string.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ryan Welton <Ryan.G.Welton@gmail.com>");
MODULE_DESCRIPTION("A vulnerable proc entry");
MODULE_VERSION("1.3.3.7");

const char procEntryName[] = "vulnEntry";

int procWrite(struct file *file, const char *buf,unsigned long count, void *data)
{
    return count;
}

int procRead(char *page, char **start, off_t off, int count, int *eof, void *data)
{
    #define MAX_LENGTH 100
    char buf[MAX_LENGTH];

    printk(KERN_INFO "csaw: called csaw_read\n");

    *eof = 1;
    memset(buf, 0, sizeof(buf));
    strcpy(buf, "Welcome to the CSAW CTF challenge. Best of luck!\n");
    memcpy(page, buf + off, MAX_LENGTH);

    return MAX_LENGTH;
}

/*
struct file_operations proc_fops = {
  read: procRead,
  write: procWrite
};
*/

void setupProcStructure(void)
{
    struct proc_dir_entry *vulnProcEntry;
    vulnProcEntry  = create_proc_entry(procEntryName, 0666, NULL);
    vulnProcEntry->write_proc = procWrite;
    vulnProcEntry->read_proc = procRead;
}


int __init mod_init(void)
{
    setupProcStructure();
    return 0; //A non 0 return means init_module failed; module can't be loaded.
}

void __exit mod_exit(void)
{
    remove_proc_entry(procEntryName, NULL);
    printk(KERN_INFO "Vulnerable LKM unloaded\n");
}

module_init(mod_init);
module_exit(mod_exit);

